package com.yenlien.traceyun.control.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.control.dao.MessageDao;
import com.yenlien.traceyun.control.entity.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.beans.Transient;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MessageService {

    @Autowired
    private MessageDao messageDao;


    /**
     * 数据中心保存数据，进入待发送状态
     */
    @Transient
    public Object save(JSONObject params) {        //保存消息列表
        List<Message> li = new ArrayList<>();
        JSONArray companyIdList = params.getJSONArray("companyIdList");
        if (!StringUtils.isEmpty(params.get("pid"))) {
            List<Message> byPid = messageDao.findByPid(params.getString("pid"));
            if (byPid != null && byPid.size() > 0) {
                messageDao.deleteByPid(params.getString("pid"));
            }
        }
        String pid = String.valueOf(System.currentTimeMillis());
        for (int i = 0; i < companyIdList.size(); i++) {
            JSONObject obj = companyIdList.getJSONObject(i);
            Message message = new Message();
            message.setState(0);        //未读
            message.setCompanyId(obj.getString("companyId"));
            message.setCreatetime(new Date());
            message.setTitle(params.getString("title"));
            message.setContent(params.getString("content"));
            message.setAppName(params.getString("appName"));
            message.setPid(pid);
            message.setCompanyName(obj.getString("companyName"));
            message.setType("0");           //（0.未读，1。已读）
            li.add(message);
        }
        return messageDao.saveAll(li);
    }

    /**
     * 用户端查询单条数据，根据id查询
     */
    public Object findById(String id) {
        return messageDao.findById(id);
    }

    /**
     * 数据中心的编辑功能   首先根据pid进行数据查询找出修改的这条数据
     */
    public Object findByPid(String pid) {
        Message mesg = new Message();
        List<Message> msg = messageDao.findByPid(pid);
        if (msg.size() > 0) {
            Message message = msg.get(0);
            mesg.setPid(message.getPid());
            mesg.setCompanyName(message.getCompanyName());
            mesg.setAppName(message.getAppName());
            mesg.setState(message.getState());
            mesg.setContent(message.getContent());
            mesg.setTitle(message.getTitle());
            StringJoiner sj = new StringJoiner(",");
            for (Message message1 : msg) {
                sj.add(message1.getCompanyName());
            }
            mesg.setCompanyName(sj.toString());
        }
        return mesg;
    }

    /**
     * 数据中心根据pid进行消息删除   （删除的是整个pid下面的消息）
     */
    public Object deleteByPid(String pid) {
        return messageDao.deleteByPid(pid);
    }

    /**
     * 针对用户的一个读取消息的一个状态更改
     */
    public Object updateStatus(String id) {
        return messageDao.updateState(id);
    }

    /**
     * 数据中心群发消息
     */
    public Object updateAllStatus(String pid) {
        return messageDao.updateAllStatus(pid);
    }

    /**
     * 数据中心的编辑功能
     */
    public Object updateAll(JSONObject params) {
        List<Message> li = new ArrayList<>();
        JSONArray companyIdList = params.getJSONArray("companyIdList");
        messageDao.deleteByPid(params.getString("pid"));

        for (int i = 0; i < companyIdList.size(); i++) {
            String companyId = companyIdList.getString(i);
            Message message = new Message();
            message.setState(0);        //未读
            message.setCompanyId(companyId);
            message.setCreatetime(new Date());
            message.setTitle(params.getString("title"));
            message.setContent(params.getString("content"));
            message.setAppName(params.getString("appName"));
            message.setPid(String.valueOf(System.currentTimeMillis()));
            li.add(message);
        }
        return messageDao.saveAll(li);
    }

    /**
     * 针对用户的一个列表查询（分状态处理）
     */
    public Page<Message> findByList(final Message message) {
        Pageable pageable = PageRequest.of(message.getPage(), message.getPageSize(), Sort.Direction.DESC, "createtime");
        return messageDao.findAll(new Specification<Message>() {
            private static final long serialVersionUID = 1L;

            @Override
            public Predicate toPredicate(Root<Message> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                //构造查询条件
                List<Predicate> list = new ArrayList<>();
                if (!StringUtils.isEmpty(message.getCompanyId())) {
                    list.add(cb.equal(root.get("companyId"), message.getCompanyId()));
                }
                Predicate[] predicate = new Predicate[list.size()];
                return cb.and(list.toArray(predicate));
            }
        }, pageable);
    }

    /**
     * 发送消息数据中心----整个列表查询
     */
    public Page<Message> findByListSend(final Message message) {
        Pageable pageable = PageRequest.of(message.getPage(), message.getPageSize(), Sort.Direction.DESC, "createtime");
//        Page<Message> pid = messageDao.findAll(new Specification<Message>() {
//            private static final long serialVersionUID = 1L;
//            @Override
//            public Predicate toPredicate(Root<Message> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//                //构造查询条件
//                List<Predicate> list = new ArrayList<>();
//                query.groupBy(root.get("pid"));
//                Predicate[] predicate = new Predicate[list.size()];
//                return cb.and(list.toArray(predicate));
//            }
//        }, pageable);
        Page<Message> pid = messageDao.findAll(pageable);
        List<Message> content = pid.getContent().stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(()->new TreeSet<>(Comparator.comparing(Message::getPid))),ArrayList::new));
        return new PageImpl<>(content, pageable, pid.getTotalElements());
    }

    /**
     * 查询所有
     */
    public List<Message> findByAll() {
        return messageDao.findAll();
    }
}
